#include "driver.h"
#include "driver_opengl.h"
#include <map>
#include <iostream>

namespace krryn{
namespace system_imp{

class driver_helper{
public:
	static driver_helper *get_instance(){
		if(m_Instance == 0){
			m_Instance = new driver_helper();
		}

		return m_Instance;
	}

	void attach(const std::string &a_Name, system::driver_factory *a_Registration){
		std::clog << "Registered " << a_Name << " driver" << std::endl;

		m_Factories[a_Name] = a_Registration;
	}

	system::driver_factory *get(){
		if(m_Factories.size() > 0){
			loaded(m_Factories.begin()->first);
			return m_Factories.begin()->second;
		}

		throw system::subsystem_not_found("Can't load default subsystem!");
	}

	system::driver_factory *get(const std::string a_Name){
		system::driver_factory *a_Factory = m_Factories[a_Name];

		if(a_Factory == 0)
			throw system::subsystem_not_found(a_Name);

		loaded(a_Name);
		return a_Factory;
	}

private:
	void loaded(const std::string &a_Name){
		std::clog << "Loaded " << a_Name << " driver" << std::endl;
	}

	std::map<std::string, system::driver_factory*> m_Factories;
	static driver_helper *m_Instance;
};

driver_helper* driver_helper::m_Instance = 0;
}
}

using namespace krryn::system;
using namespace krryn::system_imp;

void driver::attach(const std::string &a_Name, driver_factory *a_Registration){
	driver_helper::get_instance()->attach(a_Name, a_Registration);
}

driver *driver::create(){
	return driver_helper::get_instance()->get()->create();
}

driver *driver::create(const std::string &a_Name){
	return driver_helper::get_instance()->get(a_Name)->create();
}
